/*
This is part of Screenbar, which is based in part on the Litestep
shell source code.

Copyright (C) 2008-2009 Jim Babcock
Copyright (C) 1997-2009 The LiteStep Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#pragma once

/////////////////////////////////////////////////////////////////////////////

class NullElement
	:public LayoutElement
{
public:
	NullElement();
	
	ElementSize getLength(const LayoutCacheNode *node);
};

/////////////////////////////////////////////////////////////////////////////

class SpacerElement
	:public LayoutElement
{
public:
	SpacerElement(int size, bool optional, bool expanding);
	ElementSize getLength(const LayoutCacheNode *node);
	bool isExpanding();
	
protected:
	string spacerElementName(int size, bool optional, bool expanding);
	
	int size;
	bool optional;
	bool expanding;
};

/////////////////////////////////////////////////////////////////////////////

class RectLayoutElement
	:public LayoutElement
{
public:
	RectLayoutElement(string prefix);
	
	ElementSize getLength(const LayoutCacheNode *node);
	
protected:
	Rect getRect(Rect contextRect);
	
	string x, y, width, height;
	int minLength, preferredLength;
	
	bool useAspectRatio;
	float aspectRatio;
};

/////////////////////////////////////////////////////////////////////////////

class GroupElement
	:public LayoutElement
{
public:
	GroupElement(string prefix);
	~GroupElement();
	
	ElementSize getLength(const LayoutCacheNode *node);
	void getChildren(LayoutCacheNode *node, vector<LayoutLocation> &outChildren);
	
protected:
	int baseLength;
	vector<LayoutElement*> children;
};

/////////////////////////////////////////////////////////////////////////////

class StartButtonElement
	:public LayoutElement
{
public:
	StartButtonElement(string prefix);
	~StartButtonElement();
	
	void deleteElementData(LayoutCacheNode *node, void *elementData);
	void getChildren(LayoutCacheNode *node, vector<LayoutLocation> &outChildren);
	void press(LayoutCacheNode *node);
	bool allowAutoHide(LayoutCacheNode *nod);
	
protected:
	LayoutElement *raisedChild;
	LayoutElement *pressedChild;
	string command;
};

/////////////////////////////////////////////////////////////////////////////

class TextLabelElement
	:public LayoutElement
{
public:
	TextLabelElement(string prefix);
	~TextLabelElement();
	
	bool changed(const LayoutCacheNode *node);
	void update(LayoutCacheNode *node);
	void deleteElementData(LayoutCacheNode *node, void *elementData);
	ElementSize getLength(const LayoutCacheNode *node);
	void draw(HDC drawContext, const LayoutCacheNode *node);
	
protected:
	enum {
		labelAuto,
		labelCustom,
		
		labelDeskNum,
		labelTaskName,
		labelTaskPID,
		labelTaskCPU,
		labelTaskMem,
	} text;
	string getText(const ElementContext *context);
	SIZE measureText(const LayoutCacheNode *node, const string &text);
	
	Alignment alignHoriz;
	Alignment alignVert;
	string x, y;
	string minLength;
	string maxLength;
	string customText;
	bool allowAbbrev;
#ifdef USE_LSPAINT
	TextPainter *font;
#else
	PaintText *font;
#endif
	bool useStatsClass;
};

/////////////////////////////////////////////////////////////////////////////

class TextureElement
	:public RectLayoutElement
{
public:
	TextureElement(string prefix);
	~TextureElement();
	
	void draw(HDC drawContext, const LayoutCacheNode *node);
	
protected:
#ifdef USE_LSPAINT
	TexturePainter *texture;
#else
	PaintTexture *texture;
#endif
};

/////////////////////////////////////////////////////////////////////////////

class TaskIconElement
	:public RectLayoutElement
{
public:
	TaskIconElement(string prefix);
	~TaskIconElement();

	void draw(HDC drawContext, const LayoutCacheNode *node);
	
protected:
	float offsetX, offsetY;
	bool useXPaintClass;
#ifdef USE_LSPAINT
	IconPainter *iconPainter;
#else
	PaintIcon *iconPainter;
#endif
};
